#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <mqueue.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "queue.h"

int send_msg(const char *qname, const char *msg, int len, int flag, int prio)
{
	mqd_t fd = mq_open(qname, O_WRONLY | flag);
	if (fd == (mqd_t)-1 && errno == ENOENT) {
		fd = mq_open(qname, O_RDWR | O_CREAT | O_EXCL, 0666, NULL);
		if (fd == (mqd_t)-1) {
			return -1;
		}
	}
	len = mq_send(fd, msg, len, prio);
	if (len < 0) {
		mq_close(fd);
		return -1;
	}
	mq_close(fd);
	return len;
}

int recv_msg(const char *qname, char *buf, int len, int flag)
{
	mqd_t fd = mq_open(qname, O_RDONLY | flag);
	if (fd == (mqd_t)-1 && errno == ENOENT) {
		fd = mq_open(qname, O_RDWR | O_CREAT | O_EXCL, 0666, NULL);
		if (fd == (mqd_t)-1) {
			return -1;
		}
	}
	len = mq_receive(fd, buf, len, NULL);
	if (len < 0) {
		mq_close(fd);
		return -1;
	}
	buf[len] = 0;
	mq_close(fd);
	return len;
}

int timerecv_msg(const char *qname, char *buf, int len, int timeout)
{
	mqd_t fd = mq_open(qname, O_RDONLY);
	if (fd == (mqd_t)-1 && errno == ENOENT) {
		fd = mq_open(qname, O_RDWR | O_CREAT | O_EXCL, 0666, NULL);
		if (fd == (mqd_t)-1) {
			return -1;
		}
	}
	struct timespec tmc;
	tmc.tv_nsec = 0;
	tmc.tv_sec = time(NULL) + timeout;
	len = mq_timedreceive(fd, buf, len, 0, &tmc);
	if (len < 0) {
		mq_close(fd);
		return -1;
	}
	buf[len] = 0;
	mq_close(fd);
	return len;
}